import 'dart:convert';

import 'package:crypto/crypto.dart';
import 'package:flutter_menu/app_config.dart';
import 'package:flutter_menu/biz/login/login_pg.dart';
import 'package:flutter_menu/exception/api_exception.dart';
import 'package:flutter_menu/model/login_model.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';

import '../../data/menu_repository.dart';
import '../../exception/account_exception.dart';
import '../../menu_page.dart';
import '../../res/app_design.dart';

class LoginController extends GetxController {
  final MenuRepository _api = Get.find();
  final AppConfig _config = Get.find();
  Rx<EdCtr?> storeIdCtr = Rx<EdCtr?>(null);
  EdCtr jbIdCtr = EdCtr(hint: "job_id".tr);
  EdCtr pwdCtr = EdCtr(hint: "pwd".tr);
  RxString version = RxString("");
  RxBool isLogin = RxBool(false);
  RxBool isConfirm = RxBool(false);
  String? _storeId;
  LoginArgs? _loginArgs;
  RxBool enableLogin = RxBool(false);
  bool obscureText = true;
  Country? country;
  bool cleanStore  = false;

  bool get startFromHome => _loginArgs != null;


  @override
  void onInit() {
    super.onInit();
    var arguments = Get.arguments;
    if(arguments != null && arguments is LoginArgs){
      _loginArgs  =arguments;
    }

    storeId = _config.storeId;
    country = _config.country ?? Country.indonesia;

    version.value = "V ${_config.versionName}";
    if(startFromHome) onStartFromHome();
  }

  set storeId(String? id) {
    _storeId = id;
    _storeId ?? {storeIdCtr.value = EdCtr(hint: "store_id".tr)};
  }




  void onStartFromHome(){
    UserModel? loginInfo =   _config.loginModel;
    if(loginInfo != null){
      jbIdCtr.ctr.text = loginInfo.nickName??"";
      jbIdCtr.enabled = false;

    }
  }

  void onLogin() async {
    try {
      SmartDialog.showLoading();
      cleanEdCtr();
      String account = jbIdCtr.ctr.text;
      String pwd = pwdCtr.ctr.text;
      if (pwd.length < 6) throw PwdException();
      pwd = md5.convert(utf8.encode(pwd)).toString();

      var bind = _storeId == null ? true : false;
      var req = await genLoginReq();
      UserModel? user;
      if (bind) {
        user = await _api.loginByNet(req, account, pwd,clean: cleanStore);
      } else {
        user = await _api.loginByDB(req, account, pwd);
      }
      if (user == null) throw PwdException();

      AppConfig.instance.loginModel = user;
      if(startFromHome){
        _loginArgs?.invoke?.call();
      }else{
        goSetting();
      }
    } on ApiException catch (e) {
      //todo 替换错误码
      if (e.code == 22) {
        storeIdCtr.value?.eMsg.value = e.message;
      } else {
        SmartDialog.showToast(e.message);
      }
    } on PwdException catch (e) {
      pwdCtr.eMsg.value = "e_account_pwd".tr;
    } on AccountNoPermissionException catch (e) {
      SmartDialog.showToast("e_account_no_permission".tr);
    } finally {
      SmartDialog.dismiss();
    }

  }


  void goSetting(){
    Get.offAndToNamed(MenuPages.Menu_Setting);
  }




  Future<LoginReq> genLoginReq() async{

    String model = _config.model??"";
    String deviceName =_config.deviceName?? "";
    String sn =_config.SN?? "";
    String deviceId = _config.deviceId?? "";
    String ip = _config.intranetIp ?? "";
    String version = _config.versionName ?? "";

    String shopId = _storeId ?? storeIdCtr.value!.ctr.text;
    var req = LoginReq(deviceId, deviceName, sn, ip, version, model, shopId);
    return req;
  }


  void cleanEdCtr() {
    var list = [storeIdCtr.value, jbIdCtr, pwdCtr];
    for (var e in list) {
      e?.eMsg.value = "";
    }
  }


  void onEdTextChange() {
    List<EdCtr> s = [jbIdCtr, pwdCtr];
    var store = storeIdCtr.value;
    if (store != null) s.add(store);
    for (var e in s) {
      if (e.ctr.text.trim().isEmpty) {
        enableLogin.value = false;
        return;
      }
    }
    enableLogin.value = true;
  }

  void goStoreLogin() {
    storeId = null;
    cleanStore = true;
  }

  void goHome() {
    _config.afterLogin  =true;
    Get.offAndToNamed(MenuPages.Menu_Order);

  }

  void exEye() {
    obscureText = !obscureText;
    update();
  }

  void confirmCountry() {
    _config.country = country;
    _api.changeApiUrl();
    update();
  }

  void selectCountry(Country c) {
    this.country = c;
    SmartDialog.dismiss();
    update();
  }

  void showCountries(BuildContext ctx) {
    SmartDialog.showAttach(
        builder: (_) {
          return CountrySelect();
        },
        animationType: SmartAnimationType.scale,
        maskColor: Colors.transparent,
        targetContext: ctx);
  }
}

class EdCtr {
  TextEditingController ctr = TextEditingController();
  RxString eMsg = RxString("");
  String? hint;
  bool enabled ;
  EdCtr({this.hint,this.enabled =true});
}


class LoginArgs{
  bool startFromHome ;
  Future<dynamic>?  Function()? invoke;

  LoginArgs( {this.invoke,this.startFromHome=true});
}


